package com.rongji.dfish.demo.editor.service;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.rongji.dfish.base.DfishException;
import com.rongji.dfish.base.Utils;
import com.rongji.dfish.base.util.StringUtil;
import com.rongji.dfish.demo.constant.DemoConstants;
import com.rongji.dfish.demo.entity.DfishView;
import com.rongji.dfish.demo.entity.DfishViewDir;
import com.rongji.dfish.framework.dao.PubCommonDAO;
import com.rongji.dfish.framework.service.BaseService;

@Service
public class EditorDirService extends CommonService<DfishViewDir> {

	@Autowired
	private PubCommonDAO pubCommonDAO;
	@Autowired
	public EditorService editorService;
	
	public PubCommonDAO getPubCommonDAO() {
		return pubCommonDAO;
	}
	
	public void setPubCommonDAO(PubCommonDAO pubCommonDAO) {
		this.pubCommonDAO = pubCommonDAO;
	}

	public EditorService getEditorService() {
		return editorService;
	}
	
	public void setEditorService(EditorService editorService) {
		this.editorService = editorService;
	}
	
	@Override
    protected void checkEntity(Object object, boolean checkPk) {
		if (object == null) {
			return;
		}
		super.checkEntity(object, checkPk);
		Date now = new Date(System.currentTimeMillis());
		if (object instanceof DfishViewDir) {
			DfishViewDir cast = (DfishViewDir) object;
			if (isDirNameRepeat(cast.getDirId(), cast.getDirName(), cast.getDirParent(), cast.getDirCreator())) {
				throw new RuntimeException(new DfishException("名称不允许重复"));
			}
			// 理论上dirId不可能为空
			String parentId = cast.getDirParent();
			DfishViewDir pDir = null;
			if (!DemoConstants.ID_ROOT.equals(parentId)) {
				pDir = getOne(DfishViewDir.class, parentId);
			}
			String pDirPath = "";
			if (pDir == null) {
				cast.setDirParent(DemoConstants.ID_ROOT);
			} else {
				pDirPath = pDir.getDirPath();
			}
			cast.setDirPath(pDirPath + "/" + cast.getDirId());
			cast.setUpdateTime(now);
		} else if (object instanceof DfishView) {
			DfishView cast = (DfishView) object;
			if (isEditorNameRepeat(cast.getViewId(), cast.getViewName(), cast.getViewDir())) {
				throw new RuntimeException(new DfishException("名称不允许重复"));
			}
			DfishView oldView = getOne(DfishView.class, cast.getViewId());
			if (oldView == null) {
				oldView = new DfishView();
				oldView.setCreateTime(now);
				oldView.setViewStatus(EditorService.STATUS_EDIT);
				oldView.setViewVersion(1L);
				// 第一次保存数据源头应该是其本身
				oldView.setViewOrigin(cast.getViewId());
			}
			cast.setUpdateTime(now);
			cast.setCreateTime(oldView.getCreateTime());
			cast.setViewStatus(oldView.getViewStatus());
			cast.setViewVersion(oldView.getViewVersion());
			cast.setViewOrigin(oldView.getViewOrigin());
		}
    }
	
	public boolean isDirNameRepeat(String dirId, String dirName, String dirParent, String dirCreator) {
		List<?> result = pubCommonDAO.getQueryList("SELECT t.dirId FROM DfishViewDir t WHERE t.dirParent=? AND t.dirCreator=? AND t.dirName=? AND t.dirId<>?",
				new Object[]{ dirParent, dirCreator, dirName, dirId });
		return Utils.notEmpty(result);
	}
	
	public boolean isEditorNameRepeat(String editorId, String editorName, String editorDir) {
		List<?> result = pubCommonDAO.getQueryList("SELECT t.viewId FROM DfishView t WHERE t.viewDir=? AND t.viewName=? AND t.viewId<>?",
				new Object[]{ editorDir, editorName, editorId });
		return Utils.notEmpty(result);
	}

	public DfishViewDir getViewDir(String dirId) {
        DfishViewDir result = (DfishViewDir) pubCommonDAO.queryAsAnObject("FROM DfishViewDir t WHERE t.dirId=?", dirId);
		return result;
	}

	public String getViewDirPath(String dirPath){
		if(dirPath==null){
			return "";
		}
		String[] dirPaths = dirPath.split("/");
		String result = "";
		for (String dirPathed:dirPaths) {
			if(!dirPathed.equals("")) {
				result +="/"+ (String)pubCommonDAO.queryAsAnObject("SELECT t.dirName FROM DfishViewDir t WHERE t.dirId=?", dirPathed);
			}
		}
		return result;
	}
	
	public int getViewNumber(String dirId,String category) {
		if (dirId.equals(DemoConstants.ID_ROOT)) {
			return ((Number)(pubCommonDAO.queryAsAnObject("SELECT COUNT(t.viewId) FROM DfishView t WHERE t.viewStatus='0' AND t.category=?", category))).intValue();
		} else {
			return ((Number)(pubCommonDAO.queryAsAnObject("SELECT COUNT(t1.viewId) FROM DfishView t1 WHERE t1.viewStatus='0' AND t1.category=? AND " +
					"EXISTS(SELECT t2.dirId FROM DfishViewDir t2 WHERE t2.dirPath LIKE ? AND t1.viewDir=t2.dirId)",new Object[]{ category , "%"+dirId+"%"}))).intValue();	
		}
	}
	
	public int getDirNumber(String dirId,String category) {
		if (dirId.equals(DemoConstants.ID_ROOT)) {
			return ((Number)(pubCommonDAO.queryAsAnObject("SELECT COUNT(t.dirId) FROM DfishViewDir t WHERE t.category=?", category))).intValue();
		} else {
			return ((Number)(pubCommonDAO.queryAsAnObject("SELECT COUNT(t.dirId) FROM DfishViewDir t WHERE t.category=? AND t.dirPath LIKE ?", new Object[]{ category , "%"+dirId+"%"}))).intValue()-1;
		}
	}
	
	
//	public int[] getViewDirCount(String dirId) {
//		int[] str = {0,0};
//		String hh = "0";
//		if (dirId.equals(DemoConstants.ID_ROOT)) {
//			str[0] =  ((Number)(pubCommonDAO.queryAsAnObject("SELECT COUNT(t.dirId) FROM DfishViewDir t WHERE t.category=?", hh))).intValue();
//			str[1] =  ((Number)(pubCommonDAO.queryAsAnObject("SELECT COUNT(t.viewId) FROM DfishView t WHERE t.viewStatus=?", hh))).intValue();;
//		} else {
//			str[0] = ((Number)(pubCommonDAO.queryAsAnObject("SELECT COUNT(t.dirId) FROM DfishViewDir t WHERE t.dirPath LIKE ?", "/"+dirId+"%"))).intValue()-1;
//			str[1] = ((Number)(pubCommonDAO.queryAsAnObject("SELECT COUNT(t1.viewId) FROM DfishView t1 WHERE t1.viewStatus='0' AND " +
//					"EXISTS(SELECT t2.dirId FROM DfishViewDir t2 WHERE t2.dirPath LIKE ? AND t1.viewDir=t2.dirId)","/"+ dirId+"%"))).intValue();
//		}
//		
//		return str;
//		
//	}
	
//    public List<DfishViewDir> findSubViewDirs(Page page, String dirId) {
//    	// FIXME Page未进行处理
//    	@SuppressWarnings("unchecked")
//        List<DfishViewDir> result = (List<DfishViewDir>) pubCommonDAO.getQueryList("FROM DfishViewDir t WHERE t.dirParent=? ORDER BY t.dirOrder", dirId);
//		if (result == null) {
//			return Collections.emptyList();
//		}
//		return result;
//    }
    
    public List<DfishViewDir> findDirs(String dirCreator) {
    	if (Utils.isEmpty(dirCreator)) {
    		return Collections.emptyList();
    	}
    	@SuppressWarnings("unchecked")
        List<DfishViewDir> dirs = (List<DfishViewDir>) pubCommonDAO.getQueryList("FROM DfishViewDir t WHERE t.dirCreator=?", new Object[]{ dirCreator });
    	return dirs;
    }
    
    public List<DfishViewDir> findRootDirs(String dirCreator) {
    	if (Utils.isEmpty(dirCreator)) {
    		return Collections.emptyList();
    	}
    	@SuppressWarnings("unchecked")
        List<DfishViewDir> result = (List<DfishViewDir>) pubCommonDAO.getQueryList("FROM DfishViewDir t WHERE t.dirCreator=? AND t.dirParent=? ORDER BY t.dirParent,t.dirOrder", new Object[]{ dirCreator, DemoConstants.ID_ROOT });
    	return result;
    }
    
    public List<DfishViewDir> findSubDirs(String dirId) {
    	if (Utils.isEmpty(dirId)) {
    		return Collections.emptyList();
    	}
    	
        @SuppressWarnings("unchecked")
        List<DfishViewDir> result = (List<DfishViewDir>) pubCommonDAO.getQueryList("FROM DfishViewDir t WHERE t.dirParent=? ORDER BY t.dirParent,t.dirOrder", new Object[]{  dirId });
	    return result;
    }
    
    public List<DfishViewDir> findPathDirs(String dirPath) {
    	if (Utils.isEmpty(dirPath)) {
    		return Collections.emptyList();
    	}
    	@SuppressWarnings("unchecked")
        List<DfishViewDir> dirList = (List<DfishViewDir>) pubCommonDAO.getQueryList("FROM DfishViewDir t WHERE t.dirPath LIKE ? ORDER BY t.dirPath", new Object[]{ dirPath + "%" });
    	return dirList;
    }
    
    public static Map<String, List<DfishViewDir>> getPathDirs(List<DfishViewDir> dirList) {
    	Map<String, List<DfishViewDir>> result = new HashMap<String, List<DfishViewDir>>();
    	if (Utils.notEmpty(dirList)){
    		for (DfishViewDir data : dirList) {
    			String pId = data.getDirParent();
    			if (DemoConstants.ID_ROOT.equals(pId)) {
    				pId = DemoConstants.ITEM_USER + data.getDirCreator();
    			}
    			List<DfishViewDir> tempList = result.get(pId);
    			if (tempList == null) {
    				tempList = new ArrayList<DfishViewDir>();
    				result.put(pId, tempList);
    			}
    			tempList.add(data);
    		}
    	}
    	return result;
    }
    
    public Map<String, DfishViewDir> findDirsBatch(String... dirId) {
    	if (Utils.isEmpty(dirId)) {
    		return Collections.emptyMap();
    	}
    	@SuppressWarnings("unchecked")
        List<DfishViewDir> dirList = (List<DfishViewDir>) pubCommonDAO.getQueryList("FROM DfishViewDir t WHERE t.dirId IN (" + BaseService.getParamStr(dirId.length) + ")", dirId);
    	Map<String, DfishViewDir> result = new HashMap<String, DfishViewDir>();
    	for (DfishViewDir dir : dirList) {
    		result.put(dir.getDirId(), dir);
    	}
    	return result;
    }
    
    public Map<String, String> findDirNamesBatch(String... dirId) {
    	if (Utils.isEmpty(dirId)) {
    		return Collections.emptyMap();
    	}
    	@SuppressWarnings("unchecked")
        List<Object[]> dirList = (List<Object[]>) pubCommonDAO.getQueryList("SELECT t.dirId,t.dirName FROM DfishViewDir t WHERE t.dirId IN (" + BaseService.getParamStr(dirId.length) + ")", dirId);
    	Map<String, String> result = new HashMap<String, String>();
    	for (Object[] dir : dirList) {
    		result.put((String) dir[0], (String) dir[1]);
    	}
    	return result;
    }

//    @SuppressWarnings("unchecked")
//    public List<DfishViewDir> findViewDirs4Path(String dirId, String category) {
//    	if (Utils.isEmpty(dirId)) {
//    		return Collections.emptyList();
//    	}
//    	
//        DfishViewDir currDir = (DfishViewDir) pubCommonDAO.queryAsAnObject("FROM DfishViewDir t WHERE t.dirId=?", dirId);
//        List<DfishViewDir> dirs = null;
//        Set<String> mainPath = new HashSet<String>();
//        if (currDir != null) {
//        	String dirPath = currDir.getDirPath();
//        	for (String dir : dirPath.split("/")) {
//        		if (Utils.notEmpty(dir)) {
//        			mainPath.add(dir);
//        		}
//        	}
//        	String rootId = currDir.getDirRoot();
//        	dirs = (List<DfishViewDir>) pubCommonDAO.getQueryList("FROM DfishViewDir t WHERE t.category=? AND (t.dirRoot=? OR t.dirParent=?) ORDER BY t.dirParent,t.dirOrder", new Object[]{ category, rootId, DemoConstants.ID_ROOT });
//        } else {
//        	dirs = (List<DfishViewDir>) pubCommonDAO.getQueryList("FROM DfishViewDir t WHERE t.category=? AND t.dirParent=? ORDER BY t.dirParent,t.dirOrder", new Object[]{ category, DemoConstants.ID_ROOT });
//        }
//    	if (Utils.isEmpty(dirs)) {
//    		return Collections.emptyList();
//    	}
//    	
//	    return dirs;
//    }
    
    public Long getDirNewOrder(String dirParent, String dirCreator) {
		Number newOrder = null;
		if (Utils.notEmpty(dirParent) && Utils.notEmpty(dirCreator)) {
			newOrder = (Number) pubCommonDAO.queryAsAnObject("SELECT MAX(t.dirOrder) FROM DfishViewDir t WHERE t.dirParent=? AND t.dirCreator=?", new Object[]{ dirParent, dirCreator });
		}
		if (newOrder == null) {
			newOrder = 0L;
		}
		return newOrder.longValue() + 10L;
	}
    
    @SuppressWarnings("unchecked")
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void moveDir(String dirId, String moveType) {
    	if (Utils.isEmpty(dirId) || Utils.isEmpty(moveType)) {
    		return;
    	}
    	DfishViewDir dir = get(dirId);
    	List<Object[]> dataList = (List<Object[]>) pubCommonDAO.getQueryList("SELECT t.dirId,t.dirOrder FROM DfishViewDir t WHERE t.dirParent=? AND t.dirCreator=? ORDER BY t.dirOrder", new Object[]{ dir.getDirParent(), dir.getDirCreator() });
    	final List<Object[]> updateData = getData4Update(dataList, dirId, moveType);
    	pubCommonDAO.getHibernateTemplate().execute(new HibernateCallback<Object>() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
            	Query update = session.createQuery("UPDATE DfishViewDir t SET t.dirOrder=? WHERE t.dirId=?");
            	for (Object[] d : updateData) {
            		update.setParameter(0, d[1]);
            		update.setParameter(1, d[0]);
            		update.executeUpdate();
            	}
	            return null;
            }
		});
//    	if (MOVE_TOP.equals(moveType)) { // 置顶
//    		pubCommonDAO.bulkUpdate("UPDATE DfishViewDir t SET t.dirOrder=t.dirOrder+10 WHERE t.dirParent=? AND EXISTS(SELECT t2.dirOrder FROM DfishViewDir t2 WHERE t.dirId=? AND t.dirOrder<t2.dirOrder)", new Object[]{ pDir, dirId });
//    		pubCommonDAO.bulkUpdate("UPDATE DfishViewDir t SET t.dirOrder=(SELECT MIN(t2.dirOrder)-10 FROM DfishViewDir t2) WHERE t.dirId=?", dirId);
//    	} else if (MOVE_BOTTOM.equals(moveType)) { // 置底
//    		pubCommonDAO.bulkUpdate("UPDATE DfishViewDir t SET t.dirOrder=t.dirOrder-10 WHERE t.dirParent=? AND EXISTS(SELECT t2.dirOrder FROM DfishViewDir t2 WHERE t.dirId=? AND t.dirOrder>t2.dirOrder)", new Object[]{ pDir, dirId });
//    		pubCommonDAO.bulkUpdate("UPDATE DfishViewDir t SET t.dirOrder=(SELECT MAX(t2.dirOrder)+10 FROM DfishViewDir t2) WHERE t.dirId=?", dirId);
//    	} else {
//    		List<Object[]> updateData = new ArrayList<Object[]>();
//    		if (MOVE_UP.equals(moveType)) { // 向上
//    			
//    			// FIXME 排序号相同的情况暂不考虑
//    			if (Utils.notEmpty(data) && data.size() >= 2) {
//    				Object[] currData = data.get(0);
//    				Object[] preData = data.get(1);
//    				updateData.add(new Object[]{ currData[1], preData[0]  });
//    				updateData.add(new Object[]{ preData[1], currData[0] });
//    			}
//    		} else { // 向下
//    			List<Object[]> data = (List<Object[]>) pubCommonDAO.getQueryList("SELECT t.dirId,t.dirOrder FROM DfishViewDir t WHERE t.dirParent=? AND EXISTS(SELECT t2.dirOrder FROM DfishViewDir t2 WHERE t2.dirId=? AND t.dirOrder>=t2.dirOrder) ORDER BY t.dirOrder ASC", new Object[]{ pDir, dirId });
//    			// FIXME 排序号相同的情况暂不考虑
//    			if (Utils.notEmpty(data) && data.size() >= 2) {
//    				Object[] currData = data.get(0);
//    				Object[] preData = data.get(1);
//    				updateData.add(new Object[]{ currData[1], preData[0]  });
//    				updateData.add(new Object[]{ preData[1], currData[0] });
//    			}
//    		}
//    		for (Object[] params : updateData) {
//    			pubCommonDAO.bulkUpdate("UPDATE DfishViewDir t SET t.dirOrder=? WHERE t.dirId=?", params);
//    		}
//    	}
    }
    
	public void fixPath() {
		@SuppressWarnings("unchecked")
        List<DfishViewDir> data = (List<DfishViewDir>) pubCommonDAO.getQueryList("FROM DfishViewDir t", new Object[]{});
		// FIXME 数量太多的情况暂不考虑
		if (Utils.notEmpty(data)) {
			Map<String, DfishViewDir> dataMap = new HashMap<String, DfishViewDir>();
			Map<String, List<DfishViewDir>> pDataMap = new HashMap<String, List<DfishViewDir>>();
			for (DfishViewDir dir : data) {
				dataMap.put(dir.getDirId(), dir);
				if (Utils.isEmpty(dir.getDirParent())) {
					dir.setDirParent(DemoConstants.ID_ROOT);
				}
				List<DfishViewDir> dirs = pDataMap.get(dir.getDirParent());
				if (dirs == null) {
					dirs = new ArrayList<DfishViewDir>();
					pDataMap.put(dir.getDirParent(), dirs);
				}
				// TODO 路径修复
			}
			
		}
	}
    
	public DfishView getView(String viewId) {
        DfishView result = (DfishView) pubCommonDAO.queryAsAnObject("FROM DfishView t WHERE t.viewId=?", viewId);
		return result;
	}
	
	public String getDirName(String ViewDir){
		String dirName = (String)pubCommonDAO.queryAsAnObject("SELECT t.dirName FROM DfishViewDir t WHERE t.dirId=?", new Object[]{ ViewDir });
		return dirName;
	}
	
	@SuppressWarnings("unchecked")
	public List<Object[]> findDirs(){
		return (List<Object[]>) pubCommonDAO.getQueryList("SELECT t.dirId,t.dirName,t.dirParent,t.dirOrder FROM DfishViewDir t ORDER BY t.dirOrder");

	}
	
//	public String getDirId(String dirName){
//		String dirId = (String) pubCommonDAO.queryAsAnObject("SELECT t.dirId FROM DfishViewDir t WHERE t.dirName=?", new Object[]{dirName});
//		return dirId;
//	}
    
	public List<DfishView> findViews(String viewDir) {
		if (Utils.isEmpty(viewDir)) {
			return Collections.emptyList();
		}
		@SuppressWarnings("unchecked")
		List<DfishView> result = (List<DfishView>) pubCommonDAO.getQueryList("FROM DfishView t WHERE t.viewDir=? AND t.viewStatus=? ORDER BY t.viewOrder", 
				new Object[]{ viewDir, EditorService.STATUS_EDIT });
		return result;
	}
	
	public List<DfishView> findAllViews(String dirCreator) {
		if (Utils.isEmpty(dirCreator)) {
			return Collections.emptyList();
		}
		@SuppressWarnings("unchecked")
		List<DfishView> result = (List<DfishView>) pubCommonDAO.getQueryList("FROM DfishView t WHERE EXISTS(SELECT t2.dirId FROM DfishViewDir t2 WHERE t2.dirId=t.viewDir AND t2.dirCreator=?) AND t.viewStatus=? ORDER BY t.viewOrder",
				new Object[]{ dirCreator, EditorService.STATUS_EDIT });
		return result;
	}
	
	public static boolean isRootDir(String dirId) {
		return Utils.isEmpty(dirId) || DemoConstants.ID_ROOT.equals(dirId) || dirId.startsWith(DemoConstants.ITEM_USER);
	}
	
	public Long getViewNewOrder(String dirId, String dirCreator) {
		Number newOrder = null;
		if (Utils.notEmpty(dirId) && Utils.notEmpty(dirCreator)) {
			newOrder = (Number) pubCommonDAO.queryAsAnObject("SELECT MAX(t.viewOrder) FROM DfishView t WHERE t.viewDir=? AND t.viewCreator=?", new Object[]{ dirId, dirCreator });
		}
		if (newOrder == null) {
			newOrder = 0L;
		}
		return newOrder.longValue() + 10L;
	}
	
	@SuppressWarnings("unchecked")
    public void moveView(String viewId, String moveType) {
    	if (Utils.isEmpty(viewId) || Utils.isEmpty(moveType)) {
    		return;
    	}
    	DfishView dfishView = getView(viewId);
    	// 取视图源和排序的关系
    	List<Object[]> dataList = (List<Object[]>) pubCommonDAO.getQueryList("SELECT t.viewOrigin,t.viewOrder FROM DfishView t WHERE t.viewDir=? AND t.viewStatus=? ORDER BY t.viewOrder", new Object[]{ dfishView.getViewDir(), DemoConstants.STATUS_EDIT });
    	final List<Object[]> updateData = getData4Update(dataList, viewId, moveType);
    	pubCommonDAO.getHibernateTemplate().execute(new HibernateCallback<Object>() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
            	// 根据视图源更新排序
            	Query update = session.createQuery("UPDATE DfishView t SET t.viewOrder=? WHERE t.viewOrigin=?");
            	for (Object[] d : updateData) {
            		update.setParameter(0, d[1]);
            		update.setParameter(1, d[0]);
            		update.executeUpdate();
            	}
	            return null;
            }
		});
    	
//    	if (MOVE_TOP.equals(moveType)) { // 置顶
//    		pubCommonDAO.bulkUpdate("UPDATE DfishView t SET t.viewOrder=t.viewOrder+10 WHERE t.viewDir=? AND EXISTS(SELECT t2.viewId FROM DfishView t2 WHERE t2.viewId=? AND t.viewOrder<t2.viewOrder)", new Object[]{ pDir, viewId });
//    		pubCommonDAO.bulkUpdate("UPDATE DfishView t SET t.viewOrder=(SELECT MIN(t2.viewOrder)-10 FROM DfishView t2) WHERE t.viewId=?", viewId);
//    	} else if (MOVE_BOTTOM.equals(moveType)) { // 置底
//    		pubCommonDAO.bulkUpdate("UPDATE DfishView t SET t.viewOrder=t.viewOrder-10 WHERE t.viewDir=? AND EXISTS(SELECT t2.viewId FROM DfishView t2 WHERE t2.viewId=? AND t.viewOrder>t2.viewOrder)", new Object[]{ pDir, viewId });
//    		pubCommonDAO.bulkUpdate("UPDATE DfishView t SET t.viewOrder=(SELECT MAX(t2.viewOrder)+10 FROM DfishView t2) WHERE t.viewId=?", viewId);
//    	} else {
//    		List<Object[]> updateData = new ArrayList<Object[]>();
//    		if (MOVE_UP.equals(moveType)) { // 向上
//    			List<Object[]> data = (List<Object[]>) pubCommonDAO.getQueryList("SELECT t.viewId,t.viewOrder FROM DfishView t WHERE t.viewDir=? AND EXISTS(SELECT t2.viewOrder FROM DfishView t2 WHERE t2.viewId=? AND t.viewOrder<=t2.viewOrder) ORDER BY t.viewOrder DESC", new Object[]{ pDir, viewId });
//    			// FIXME 排序号相同的情况暂不考虑
//    			if (Utils.notEmpty(data) && data.size() >= 2) {
//    				Object[] currData = data.get(0);
//    				Object[] preData = data.get(1);
//    				updateData.add(new Object[]{ currData[1], preData[0]  });
//    				updateData.add(new Object[]{ preData[1], currData[0] });
//    			}
//    		} else { // 向下
//    			List<Object[]> data = (List<Object[]>) pubCommonDAO.getQueryList("SELECT t.viewId,t.viewOrder FROM DfishView t WHERE t.viewDir=? AND EXISTS(SELECT t2.viewOrder FROM DfishView t2 WHERE t2.viewId=? AND t.viewOrder>=t2.viewOrder) ORDER BY t.viewOrder ASC", new Object[]{ pDir, viewId });
//    			// FIXME 排序号相同的情况暂不考虑
//    			if (Utils.notEmpty(data) && data.size() >= 2) {
//    				Object[] currData = data.get(0);
//    				Object[] preData = data.get(1);
//    				updateData.add(new Object[]{ currData[1], preData[0]  });
//    				updateData.add(new Object[]{ preData[1], currData[0] });
//    			}
//    		}
//    		for (Object[] params : updateData) {
//    			pubCommonDAO.bulkUpdate("UPDATE DfishView t SET t.viewOrder=? WHERE t.viewId=?", params);
//    		}
//    	}
    }
	
	public void move2NewDir(String itemId, String itemType, String toDir) {
		if (Utils.isEmpty(itemId) || Utils.isEmpty(toDir)) {
			throw new UnsupportedOperationException("调用移动到新目录参数不完整");
		}
		
		// FIXME 移动到目标目录下时需判断名称是否已存在
		if (DemoConstants.ITEM_FILE.equals(itemType)) { // 视图
			DfishView view = getView(itemId);
			pubCommonDAO.bulkUpdate("UPDATE DfishView t SET t.viewDir=? WHERE t.viewOrigin=?", new Object[]{ toDir, view.getViewOrigin() });
		} else { // 目录
			DfishViewDir oldDir = get(itemId);
			String oldPath = oldDir.getDirPath();
			String newPath = "";
			if(DemoConstants.ID_ROOT.equals(toDir)) {
				newPath = "/" + itemId;
			} else {
				newPath = (String) pubCommonDAO.queryAsAnObject("SELECT t.dirPath FROM DfishViewDir t WHERE t.dirId=?", toDir) + "/" + itemId;
			}
			pubCommonDAO.bulkUpdate("UPDATE DfishViewDir t SET t.dirParent=? WHERE t.dirId=?", new Object[]{ toDir, itemId });
			pubCommonDAO.bulkUpdate("UPDATE DfishViewDir t SET t.dirPath=?||SUBSTR(t.dirPath,?) WHERE t.dirPath LIKE ?", new Object[]{ newPath, oldPath.length() + 1, oldPath + "%" });
		}
	}
	
	public void deleteCascade(String id, String type) {
		if (DemoConstants.ITEM_FILE.equals(type)) {
			pubCommonDAO.bulkUpdate("DELETE FROM DfishViewNode t WHERE t.viewId=?", id);
			pubCommonDAO.bulkUpdate("DELETE FROM DfishView t WHERE t.viewId=?", id);
		} else {
			pubCommonDAO.bulkUpdate("DELETE FROM DfishViewNode t WHERE EXISTS (SELECT t2.viewId FROM DfishView t2 WHERE t2.viewDir=? AND t2.viewId=t.viewId)", id);
			pubCommonDAO.bulkUpdate("DELETE FROM DfishView t WHERE t.viewDir=?", id);
			pubCommonDAO.bulkUpdate("DELETE FROM DfishViewDir t WHERE t.dirId=?", id);
		}
	}
	
	@SuppressWarnings("unchecked")
    public void reorder(String targetDir, String orderType) {
		String sqlDir = "SELECT t.dirId,t.dirOrder,t.dirName FROM DfishViewDir t WHERE t.dirParent=?";
		String sqlView = "SELECT t.viewOrigin,t.viewOrder,t.viewName FROM DfishView t WHERE t.viewDir=? AND t.viewStatus=?";
		
		boolean orderName = DemoConstants.ORDER_NAME.equals(orderType);
		List<Object> params4Dir = new ArrayList<Object>();
		String dirId = targetDir;
		
		// 编辑器需要排序
		boolean onlyOrderDir = targetDir.startsWith(DemoConstants.ITEM_USER);
		if (onlyOrderDir) {
			dirId = DemoConstants.ID_ROOT;
			params4Dir.add(dirId);
			sqlDir += " AND t.dirCreator=?";
			params4Dir.add(targetDir.substring(DemoConstants.ITEM_USER.length()));
		} else {
			params4Dir.add(dirId);
		}
		
		if (orderName) { // 按名称
			sqlDir += " ORDER BY t.dirName";
			sqlView += " ORDER BY t.viewName";
		} else if (DemoConstants.ORDER_TIME.equals(orderType)) { // 按更新时间
			sqlDir += " ORDER BY t.updateTime";
			sqlView += " ORDER BY t.updateTime";
		} else {
			throw new UnsupportedOperationException("暂不支持其他排序方式[" + orderType + "]");
		}
		List<Object[]> dirData = (List<Object[]>) pubCommonDAO.getQueryList(sqlDir, params4Dir.toArray());
		if (orderName) {
			sortByChineseOrder(dirData);
		}
		final List<Object[]> updateDirs = new ArrayList<Object[]>();
		Long order = 0L;
		for (Object[] d : dirData) {
			order += 10L;
			if (!d[1].equals(order)) {
				d[1] = order;
				updateDirs.add(d);
			}
		}
		
		final List<Object[]> updateViews = new ArrayList<Object[]>();
		if (!onlyOrderDir) {
			List<Object[]> viewData = (List<Object[]>) pubCommonDAO.getQueryList(sqlView, new Object[]{ dirId, DemoConstants.STATUS_EDIT });
			if (orderName) {
				sortByChineseOrder(viewData);
			}
			order = 0L;
			for (Object[] d : viewData) {
				order += 10L;
				if (!d[1].equals(order)) {
					d[1] = order;
					updateViews.add(d);
				}
			}
		}
		
		pubCommonDAO.getHibernateTemplate().execute(new HibernateCallback<Object>() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
            	// 更新目录排序
            	Query queryDir = session.createQuery("UPDATE DfishViewDir t SET t.dirOrder=? WHERE t.dirId=?");
            	for (Object[] d : updateDirs) {
            		queryDir.setParameter(0, d[1]);
            		queryDir.setParameter(1, d[0]);
            		queryDir.executeUpdate();
            	}
            	// 根据视图源更新排序
            	Query queryView = session.createQuery("UPDATE DfishView t SET t.viewOrder=? WHERE t.viewOrigin=?");
            	for (Object[] d : updateViews) {
            		queryView.setParameter(0, d[1]);
            		queryView.setParameter(1, d[0]);
            		queryView.executeUpdate();
            	}
	            return null;
            }
		});
	}
	
	public void sortByChineseOrder(List<Object[]> data){
		Collections.sort(data,new java.util.Comparator<Object[]>(){
			@Override
			public int compare(Object[] o1, Object[] o2) {
				return StringUtil.CHINESE_ORDER.compare(o1[2], o2[2]);
			}
		});
	}
	
	public void copyTo(DfishView dView, String oldViewId) {
		if (Utils.isEmpty(oldViewId)) {
			throw new UnsupportedOperationException("The old ViewId can not be empty.");
		}
			
		if (Utils.isEmpty(dView.getViewId()) || dView.getViewId().equals(oldViewId)) {
			dView.setViewId(CommonService.getNewId());
		}
		checkEntity(dView, false);
		
		Date now = new Date(System.currentTimeMillis());
		dView.setUpdateTime(now);
		dView.setCreateTime(now);
		dView.setViewStatus(DemoConstants.STATUS_EDIT);
		dView.setViewVersion(1L);
		dView.setViewOrigin(dView.getViewId());
		pubCommonDAO.save(dView);
		
		editorService.copyNodes(oldViewId, dView.getViewId(), false);

	}	
}

	

